package com.ruoyi.system.service.impl;

import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.UploadConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.VideoUtil;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.system.domain.BsJingquJingdian;
import com.ruoyi.system.mapper.BsJingquJingdianMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description TODO
 * @ClassName AsyncAccessJingdianFileService
 * @Author kenn
 * @Version 1.0.0
 * @Date 2023年11月22日 14:52:00
 */
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class AsyncAccessJingdianFileService {

    private final DataSourceTransactionManager transactionManager;

    private final TransactionDefinition transactionDefinition;

    private final BsJingquJingdianMapper jingdianMapper;

    @Async("threadPoolTaskExecutor")
    public void save(BsJingquJingdian save, AtomicInteger atomicInteger, CountDownLatch latchMain, CountDownLatch latchSlave) {
        TransactionStatus transaction = transactionManager.getTransaction(transactionDefinition);
        try {
            String jingdianFile = save.getJingdianFile();
            String fileSuffix = jingdianFile.substring(jingdianFile.lastIndexOf(".") + 1);
            boolean isMedia = Arrays.stream(MimeTypeUtils.MEDIA_EXTENSION).anyMatch(i -> i.equalsIgnoreCase(fileSuffix));
            // 是音频文件
            if (isMedia) {
                long audioLength = VideoUtil.getAudioLength(jingdianFile);
                save.setDuration(audioLength);
                save.setFileType("2");
            } else {
                // 首帧路径
                String coverImgPath = RuoYiConfig.getProfile();
                String coverImgName = DateUtils.datePath() + "/" + IdUtil.fastUUID() + ".jpeg";
                File coverImgFile = new File(coverImgPath + File.separator + coverImgName);
                if (!coverImgFile.getParentFile().exists()) {
                    coverImgFile.getParentFile().mkdirs();
                }
                FileOutputStream outputStream = new FileOutputStream(coverImgFile);
                String coverImgUrl = UploadConfig.getUrl() + Constants.RESOURCE_PREFIX + "/" + coverImgName;
                long audioLength = VideoUtil.getVideoMap(jingdianFile, outputStream);
                save.setDuration(audioLength);
                save.setCoverImg(coverImgUrl);
                save.setFileType("1");
            }

            jingdianMapper.insert(save);
            latchSlave.countDown();
            latchMain.await();
        } catch (Exception e) {
            e.printStackTrace();
            atomicInteger.getAndIncrement();
            latchSlave.countDown();
        } finally {
            if (atomicInteger.get() > 0) {
                log.error("程序存在异常，程序进行回滚, 当前线程：{}", Thread.currentThread().getName());
                transactionManager.rollback(transaction);
            } else {
                //手动提交
                transactionManager.commit(transaction);
            }
        }
    }

}
